package net.zkbc.helloworld.script;

import java.util.Base64;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.PropertySourcesPropertyResolver;
import org.springframework.stereotype.Component;

import net.zkbc.helloworld.util.Cryptos;

@Component
public class DSInitScript implements BeanFactoryPostProcessor {

	private static final Logger LOG = LoggerFactory.getLogger(DSInitScript.class);

	private static final byte[] JDBC_PWD_AESKEY = Base64.getDecoder().decode("s9hT+SO8C6QrDIEj0Suyzw==");

	public static void main(String[] args) {
		System.out.println(encode("zkbc"));
		System.out.println(encode("Zkbc@2016"));
	}

	private static String decode(String str) {
		byte[] ciphertext = Base64.getDecoder().decode(str);
		byte[] plaintext = Cryptos.aesDecrypt(ciphertext, JDBC_PWD_AESKEY);
		return new String(plaintext);
	}

	private static String encode(String str) {
		byte[] plaintext = str.getBytes();
		byte[] ciphertext = Cryptos.aesEncrypt(plaintext, JDBC_PWD_AESKEY);
		return Base64.getEncoder().encodeToString(ciphertext);
	}

	/**
	 * 解密数据库连接用户名及密码
	 */
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		LOG.info("Initializing...");
		try {
			PropertySourcesPropertyResolver propertyResolver = new PropertySourcesPropertyResolver(
					beanFactory.getBean(PropertySourcesPlaceholderConfigurer.class).getAppliedPropertySources());

			String encrypt = propertyResolver.resolvePlaceholders("${jdbc.encrypt:0}");
			LOG.debug("jdbc.encrypt={}", encrypt);
			if ("0".equals(encrypt)) {
				return;
			}

			String username = decode(propertyResolver.resolvePlaceholders("${jdbc.username}"));
			String password = decode(propertyResolver.resolvePlaceholders("${jdbc.password}"));

			BeanDefinition bd = beanFactory.getBeanDefinition("dataSource");
			MutablePropertyValues pvs = bd.getPropertyValues();
			switch (bd.getBeanClassName()) {
			case "com.mchange.v2.c3p0.ComboPooledDataSource":
				pvs.add("user", username);
				pvs.add("password", password);
				break;
			case "org.springframework.jdbc.datasource.SimpleDriverDataSource":
				pvs.add("username", username);
				pvs.add("password", password);
				break;
			default:
				break;
			}
		} catch (Exception e) {
			LOG.debug(e.getMessage(), e);
		}
	}
}
